#include "smoke_monitor.h"
#include "device_state_manager.h"
#include "smart_home_ui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>

// 全局烟雾传感器数据
static smoke_sensor_data_t g_smoke_data = {0};
static bool smoke_monitor_initialized = false;

// 蜂鸣器状态
static bool buzzer_initialized = false;

// 获取当前时间戳（毫秒）
static uint32_t get_current_time_ms(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

// 初始化蜂鸣器GPIO
static int buzzer_init(void) {
    int fd;
    char gpio_str[8];
    char path[64];
    
    if (buzzer_initialized) {
        printf("烟雾监控: 蜂鸣器已经初始化过了\n");
        return 0; // 已经初始化过了
    }
    
    // 导出GPIO引脚
    fd = open("/sys/class/gpio/export", O_WRONLY);
    if (fd < 0) {
        printf("烟雾监控: 无法打开GPIO export文件\n");
        return -1;
    }
    
    snprintf(gpio_str, sizeof(gpio_str), "%d", BUZZER_GPIO);
    if (write(fd, gpio_str, strlen(gpio_str)) < 0) {
        printf("烟雾监控: GPIO %d 可能已经被导出\n", BUZZER_GPIO);
        // 继续执行，可能GPIO已经被导出了
    }
    fsync(fd);
    close(fd);
    
    // 设置GPIO方向为输出
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", BUZZER_GPIO);
    fd = open(path, O_WRONLY);
    if (fd >= 0) {
        write(fd, "out", 3);
        fsync(fd);
        close(fd);
        printf("烟雾监控: 蜂鸣器GPIO %d 初始化成功\n", BUZZER_GPIO);
    } else {
        printf("烟雾监控: 无法设置GPIO %d 方向\n", BUZZER_GPIO);
        return -1;
    }
    
    // 直接设置GPIO为关闭状态，避免递归调用
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", BUZZER_GPIO);
    fd = open(path, O_WRONLY);
    if (fd >= 0) {
        write(fd, "0", 1);
        fsync(fd);
        close(fd);
    }
    
    // 设置初始化标志
    buzzer_initialized = true;
    
    return 0;
}

// 控制蜂鸣器状态
int buzzer_set_state(bool state) {
    char path[64];
    int fd;
    const char *value = state ? "1" : "0";
    
    if (!buzzer_initialized) {
        printf("烟雾监控: 检测到蜂鸣器未初始化，正在初始化...\n");
        if (buzzer_init() != 0) {
            printf("烟雾监控: 蜂鸣器初始化失败\n");
            return -1;
        }
    }
    
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", BUZZER_GPIO);
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        printf("烟雾监控: 无法打开蜂鸣器GPIO value文件\n");
        return -1;
    }
    
    write(fd, value, 1);
    fsync(fd);
    close(fd);
    
    return 0;
}

// 初始化烟雾监控系统
int smoke_monitor_init(void) {
    if (smoke_monitor_initialized) {
        return 0; // 已经初始化过了
    }
    
    // 初始化全局数据
    memset(&g_smoke_data, 0, sizeof(smoke_sensor_data_t));
    g_smoke_data.buzzer_enabled = true; // 默认启用蜂鸣器
    g_smoke_data.last_update_time = get_current_time_ms();
    
    // 初始化蜂鸣器
    if (buzzer_init() != 0) {
        printf("烟雾监控: 蜂鸣器初始化失败\n");
        return -1;
    }
    
    smoke_monitor_initialized = true;
    printf("烟雾监控: 系统初始化成功\n");
    return 0;
}

// 获取烟雾浓度值（从UI进度条获取实际值）
uint32_t get_smoke_concentration(void) {
    // 从UI获取实际的烟雾浓度值
    int ui_density = get_smoke_density();
    
    // 确保值在有效范围内
    if (ui_density < 0) ui_density = 0;
    if (ui_density > 100) ui_density = 100;
    
    return (uint32_t)ui_density;
}

// 检查是否需要触发警报
bool check_smoke_alarm(uint32_t concentration) {
    return concentration > SMOKE_ALARM_THRESHOLD;
}

// 更新烟雾浓度值并检查警报
void update_smoke_concentration(uint32_t concentration) {
    uint32_t current_time = get_current_time_ms();
    
    // 防抖处理：如果距离上次更新时间太短，则忽略
    if (current_time - g_smoke_data.last_update_time < 100) { // 100ms防抖
        return;
    }
    
    g_smoke_data.smoke_concentration = concentration;
    g_smoke_data.last_update_time = current_time;
    
    bool should_alarm = check_smoke_alarm(concentration);
    
    // 检查警报状态变化
    if (should_alarm && !g_smoke_data.alarm_active) {
        // 需要触发警报
        trigger_smoke_alarm();
        printf("烟雾监控: 警报触发！当前浓度: %u\n", concentration);
    } else if (!should_alarm && g_smoke_data.alarm_active) {
        // 浓度降低，停止警报
        stop_smoke_alarm();
        printf("烟雾监控: 警报停止，浓度已降低: %u\n", concentration);
    }
    
    // 同步状态到设备状态管理器
    update_smoke_monitor_state(g_smoke_data.smoke_concentration, 
                              g_smoke_data.alarm_active, 
                              g_smoke_data.buzzer_enabled);
}

// 触发烟雾警报
void trigger_smoke_alarm(void) {
    g_smoke_data.alarm_active = true;
    
    if (g_smoke_data.buzzer_enabled) {
        buzzer_set_state(true);
        printf("烟雾监控: 蜂鸣器已启动\n");
    } else {
        printf("烟雾监控: 警报触发，但蜂鸣器已被禁用\n");
    }
}

// 停止烟雾警报
void stop_smoke_alarm(void) {
    g_smoke_data.alarm_active = false;
    buzzer_set_state(false);
    printf("烟雾监控: 警报已停止\n");
}

// 获取当前烟雾传感器数据
smoke_sensor_data_t get_smoke_sensor_data(void) {
    return g_smoke_data;
}

// 烟雾监控定时任务
void smoke_monitor_task(void) {
    if (!smoke_monitor_initialized) {
        return;
    }
    
    // 获取最新的烟雾浓度值
    uint32_t concentration = get_smoke_concentration();
    
    // 添加调试输出
    static uint32_t debug_task_counter = 0;
    debug_task_counter++;
    if (debug_task_counter % 5 == 0) { // 每5秒输出一次
        printf("烟雾监控任务: 浓度=%u, 阈值=%d\n", concentration, SMOKE_ALARM_THRESHOLD);
    }
    
    // 更新浓度值并检查警报
    update_smoke_concentration(concentration);
    
    // 如果警报激活，实现蜂鸣器闪烁效果
    if (g_smoke_data.alarm_active && g_smoke_data.buzzer_enabled) {
        static bool buzzer_toggle = false;
        static uint32_t last_toggle_time = 0;
        uint32_t current_time = get_current_time_ms();
        
        // 每500ms切换一次蜂鸣器状态，产生间歇性响声
        if (current_time - last_toggle_time > 500) {
            buzzer_toggle = !buzzer_toggle;
            buzzer_set_state(buzzer_toggle);
            last_toggle_time = current_time;
        }
    }
}

// 设置蜂鸣器启用状态
void set_buzzer_enabled(bool enabled) {
    g_smoke_data.buzzer_enabled = enabled;
    
    if (!enabled && g_smoke_data.alarm_active) {
        // 如果禁用蜂鸣器且当前有警报，关闭蜂鸣器但保持警报状态
        buzzer_set_state(false);
    }
    
    printf("烟雾监控: 蜂鸣器已%s\n", enabled ? "启用" : "禁用");
}

// 手动停止当前警报
void manual_stop_alarm(void) {
    if (g_smoke_data.alarm_active) {
        stop_smoke_alarm();
        printf("烟雾监控: 警报已被手动停止\n");
    }
}

// 清理烟雾监控资源
void smoke_monitor_cleanup(void) {
    if (!smoke_monitor_initialized) {
        return;
    }
    
    // 停止警报
    stop_smoke_alarm();
    
    // 释放GPIO（可选）
    if (buzzer_initialized) {
        int fd;
        char gpio_str[8];
        
        fd = open("/sys/class/gpio/unexport", O_WRONLY);
        if (fd >= 0) {
            snprintf(gpio_str, sizeof(gpio_str), "%d", BUZZER_GPIO);
            write(fd, gpio_str, strlen(gpio_str));
            fsync(fd);
            close(fd);
        }
        
        buzzer_initialized = false;
    }
    
    smoke_monitor_initialized = false;
    printf("烟雾监控: 系统已清理\n");
}
